package com.jinyou.utils.common;

//图片工具类

import com.jinyou.utils.oss.OssConfigConstants;
import com.jinyouapp.common.utils.image.BASE64DecodedMultipartFile;
import com.jinyouapp.common.utils.image.FileStoryInfo;
import com.jinyouapp.common.utils.image.ImageUtils;
import com.jinyouapp.common.utils.media.aliyun.AliOSSConfig;
import o2o.business.image.Base64ToImageUtils;
import o2o.business.image.ImageBusiness;
import o2o.system.Common;
import o2o.system.data.SYS_CONFIG_PATH;
import o2o.system.data.SYS_SETTINGS;
import org.apache.commons.io.FileUtils;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class JYImageUtils {

    public static final String FONT_NAME = "微软雅黑";
    public static final int FONT_STYLE = Font.BOLD;
    public static final int FONT_SIZE = 48;
    public static final int X = 150;
    public static final int Y = 60;

    public static final float ALPHA = 0.3F;


    //获取图片名
    public static String getImageName() {
        return Common.sdfDateNoh.format(new Date()) + ToolUtils.getNeedString(18) + ".png";
    }

    //获取jpg图片名
    public static String getJpgImageName() {
        return Common.sdfDateNoh.format(new Date()) + ToolUtils.getNeedString(18) + ".jpg";
    }

    //获取png图片名
    public static String getPngImageName() {
        return Common.sdfDateNoh.format(new Date()) + ToolUtils.getNeedString(18) + ".png";
    }

    private static AliOSSConfig getAliOssConfig() {
        return new AliOSSConfig(OssConfigConstants.ENDPOINT, OssConfigConstants.BUCKETNAME, OssConfigConstants.ACCESSKEYID, OssConfigConstants.ACCESSKEYSECRET);
    }

    //存储图片
    public static String saveImage(String folder, MultipartFile image) {
        if (OssConfigConstants.isUse) {
            FileStoryInfo fileStoryInfo = null;
            if (ValidateUtil.isNotNull(folder) && !folder.endsWith("/")) {
                folder = folder + "/";
            }
            try {
                fileStoryInfo = ImageUtils.saveImage2Oss(null, getAliOssConfig(), image, folder, false);
            } catch (Exception e) {
                e.printStackTrace();
            }
            String path = fileStoryInfo == null ? null : fileStoryInfo.getUrl();
            if (ValidateUtil.isNull(path)) {
                return path;
            }
            if (ValidateUtil.isNotNull(OssConfigConstants.IMAGEBASEURL)) {
                if (ValidateUtil.isNotNull(folder)) {
                    path = path.substring(path.indexOf(folder));
                } else {
                    path = path.contains("/") ? path.substring(path.lastIndexOf("/")) : path;
                }
                path = OssConfigConstants.IMAGEBASEURL + path;
            }
            return path;
        } else {
            try {
                image = JYImageUtils.multipartFileImgCompress(image);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
            JYFileUtils.FilePath fp = JYFileUtils.getFile(folder, getImageName());
            if (null == fp) {
                return null;
            }
            InputStream inputStream = null;
            try {
                inputStream = image.getInputStream();
            } catch (IOException e) {
                e.printStackTrace();
                inputStream = null;
            }
            try {
                ImageBusiness.transferToServer(image, fp.file);
            } catch (IllegalStateException | IOException e) {
                e.printStackTrace();
                return null;
            }

            // 上传到图片服务器
            upload2ImgServer(fp.fileFullPath, image.getName(), inputStream);

            return fp.dbFileFullPath;
        }
    }

    // 保存图片
    public static String saveImage(String folder, MultipartFile image, String text) {
        // 添加水印
        if (ValidateUtil.isNotNull(text)) {
            image = watermark(image, text);
        }
        // 压缩
        try {
            image = JYImageUtils.multipartFileImgCompress(image);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

        JYFileUtils.FilePath fp = JYFileUtils.getFile(folder, getImageName());
        if (null == fp) {
            return null;
        }
        InputStream inputStream = null;
        try {
            inputStream = image.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
            inputStream = null;
        }
        try {
            ImageBusiness.transferToServer(image, fp.file);
        } catch (IllegalStateException | IOException e) {
            e.printStackTrace();
            return null;
        }

        // 上传到图片服务器
        upload2ImgServer(fp.fileFullPath, image.getName(), inputStream);

        return fp.dbFileFullPath;
    }


    // 添加水印
    private static MultipartFile watermark(MultipartFile image, String text) {
        if (ValidateUtil.isNull(text) || image == null) {
            return image;
        }
        try {
            Image image2 = ImageIO.read(image.getInputStream());
            int width = image2.getWidth(null);
            int height = image2.getHeight(null);
//            1、创建缓存图片对象
            BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//            2、        创建JAVA绘图工具对象
            Graphics2D graphics2D = bufferedImage.createGraphics();
//            3、使用绘图工具对象，将原图绘制到缓存图片对象
            graphics2D.drawImage(image2, 0, 0, width, height, null);
//            4、使用绘图工具，将水印（文字/图片）绘制到缓存图片对象
            graphics2D.setFont(new Font(FONT_NAME, FONT_STYLE, FONT_SIZE));
            graphics2D.setColor(Color.GRAY);
            //S1-获取文字水印的宽、高
            int width1 = FONT_SIZE * getTextLength(text);
            int height1 = FONT_SIZE;
            int widthDiff = width - width1;
            int heightDiff = height - height1;
            int x = X;
            int y = Y;
            if (x > widthDiff) {
                if (widthDiff < 0) {
                    x = 0;
                } else {
                    x = widthDiff;
                }
            }
            if (y > heightDiff) {
                if (heightDiff < 0) {
                    y = 0;
                } else {
                    y = heightDiff;
                }
            }
            graphics2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, ALPHA));//设置水印
            graphics2D.drawString(text, widthDiff - x, heightDiff - y);//x:横坐标，y:纵坐标
            graphics2D.dispose();

            File file = File.createTempFile(new Date().getTime() + "", ".png");
            FileOutputStream out = new FileOutputStream(file);
            ImageIO.write(bufferedImage, "JPEG", out);
            bufferedImage.flush();
            out.flush();
            out.close();
            bufferedImage.flush();
            image = new MockMultipartFile(file.getName(), new FileInputStream(file));
        } catch (Exception e) {
            e.printStackTrace();
            return image;
        } finally {
        }
        return image;
    }

    private static int getTextLength(String text) {
        int length = text.length();

        for (int i = 0; i < text.length(); i++) {
            String s = String.valueOf(text.charAt(i));
            if (s.getBytes().length > 1) {
                length++;
            }
        }

        length = length % 2 == 0 ? length / 2 : length / 2 + 1;
        return length;
    }


    public static MultipartFile multipartFileImgCompress(MultipartFile uploadFile) throws IOException {
        return multipartFileImgCompressV2(uploadFile, 750, 0, true);
    }

    //处上传图片问题
    public static MultipartFile multipartFileImgCompressV2(MultipartFile uploadFile, Integer width, Integer height, boolean isProportion) throws IOException {
        if (null == uploadFile) {
            return uploadFile;
        }
        long imgLength = uploadFile.getSize();
        //低于200k 不用压缩
        if (imgLength < 100 * 1024) {
            return uploadFile;
        }
        BufferedImage img = ImageIO.read(uploadFile.getInputStream());
        if (isProportion) {
            double rate = ((double) img.getWidth(null)) / width + 0.1;
            height = (int) (((double) img.getHeight(null)) / rate);
        }
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        image.getGraphics().drawImage(img.getScaledInstance(width, height, Image.SCALE_AREA_AVERAGING), 0, 0, null);
        File file = File.createTempFile(new Date().getTime() + "", ".png");
        FileOutputStream out = new FileOutputStream(file);
        //       linux 下不执行 因为jdk8已经将rt.jar移除
//        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
//        encoder.encode(image);
        ImageIO.write(image, "JPEG", out);
        image.flush();
        out.flush();
        out.close();
        img.flush();
        uploadFile = new MockMultipartFile(file.getName(), new FileInputStream(file));
        return uploadFile;
    }

    //单个图片处理
    public static int compress(String filePath, int width) throws IOException {
        int height = 0;
        File srcFile = new File(filePath);
        Long length1 = srcFile.length();
        BufferedImage src = ImageIO.read(srcFile);
        //宽度小于设定宽度

        if (src.getWidth(null) < width) {
            width = src.getWidth(null);
            height = src.getHeight(null);
        } else {
            double rate = ((double) src.getWidth(null)) / (double) width + 0.1;
            height = (int) (((double) src.getHeight(null)) / rate);
        }


        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        image.getGraphics().drawImage(src.getScaledInstance(width, height, Image.SCALE_AREA_AVERAGING), 0, 0, null);
        FileOutputStream out = new FileOutputStream(srcFile);
        ImageIO.write(image, "JPEG", out);
//        linux 下不执行 因为jdk8已经将rt.jar移除
//        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
//        encoder.encode(image);
        image.flush();
        out.flush();
        out.close();
        src.flush();
        return 1;
    }

    //操作数据库文件备份
    //根据类型只会备份一份文件
    public static void fileBackUp(String srcDirPath, int backUp) throws IOException {
        File srcDir = new File(srcDirPath);
        if (!srcDir.exists() || !srcDir.isDirectory()) {
            return;
        }
        File toDir = new File(srcDir.getParentFile().getAbsolutePath() + File.separator + "BACKUP_" + backUp);
        if (toDir.exists()) {
            File files[] = toDir.listFiles();
            for (File file : files) {
                file.delete();
            }
            toDir.delete();
        }
        toDir.mkdirs();
        File[] files = srcDir.listFiles();
        for (int i = 0; i < files.length; i++) {
            if (files[i].isFile()) {
                FileUtils.copyFile(files[i], new File(toDir.getAbsolutePath() + File.separator + files[i].getName()));
            }
        }
    }

    //单个文件夹下操作
    //单个文件
    public static int DirCompress(String srcDirPath, int backUp, Integer width, Integer length) throws IOException {
        //默认超过100kb就进行压缩
        int imgLength = 100 * 1024;
        int imgWidth = 750;
        if (null != length) {
            imgLength = length * 1024;
        }
        if (null != width) {
            imgWidth = width;
        }
        //统计文件次数
        int count = 0;
        //备份文件
        fileBackUp(srcDirPath, backUp);
        File srcDirFile = new File(srcDirPath);
        if (!srcDirFile.exists() || !srcDirFile.isDirectory()) {
            return 0;
        }
        File[] files = srcDirFile.listFiles();
        for (int i = 0; i < files.length; i++) {
            if (files[i].isDirectory()) {
                continue;
            }
            if (files[i].length() > imgLength) {
                //宽度750
                count += compress(files[i].getAbsolutePath(), imgWidth);
            }
        }
        return count;
    }

    //操作所有图片文件
    public static int AllDirFileCompress(Integer width, Integer length) throws IOException {
        //统计次数
        int count = 0;
        //USER_IMAGE 用户图片
        count += JYImageUtils.DirCompress(SYS_CONFIG_PATH.IMAGE_BASE_FILE + SYS_CONFIG_PATH.USER_IMAGE, 1, width, length);
        //ADVERT_IMAGE;//广告图片
        count += JYImageUtils.DirCompress(SYS_CONFIG_PATH.IMAGE_BASE_FILE + SYS_CONFIG_PATH.ADVERT_IMAGE, 2, width, length);
        //SHOP_IMAGE;//店铺图片
        count += JYImageUtils.DirCompress(SYS_CONFIG_PATH.IMAGE_BASE_FILE + SYS_CONFIG_PATH.SHOP_IMAGE, 3, width, length);
        //GOODS_IMAGE;//商品图片
        count += JYImageUtils.DirCompress(SYS_CONFIG_PATH.IMAGE_BASE_FILE + SYS_CONFIG_PATH.GOODS_IMAGE, 4, width, length);
        //ORDER_IMAGE;//订单图片
        count += JYImageUtils.DirCompress(SYS_CONFIG_PATH.IMAGE_BASE_FILE + SYS_CONFIG_PATH.ORDER_IMAGE, 5, width, length);
        //NOTICE_IMAGE;//消息图片路径
        count += JYImageUtils.DirCompress(SYS_CONFIG_PATH.IMAGE_BASE_FILE + SYS_CONFIG_PATH.NOTICE_IMAGE, 6, width, length);
        //USER_SIGN // 用户签到上传图片路径
        count += JYImageUtils.DirCompress(SYS_CONFIG_PATH.IMAGE_BASE_FILE + SYS_CONFIG_PATH.USER_SIGN, 7, width, length);
        return count;
    }

    // base64图片处理

    /**
     * 使用 java.util.Base64.Decoder和java.util.Base64.Encoder的JDK公共API（推荐）
     * base64转Multipartfile
     *
     * @param base64
     * @return
     * @auth: yangtk
     */
    public static MultipartFile base64ToMultipart(String base64) {
        try {
            String[] baseStrs = base64.split(",");
            Base64.Decoder decoder = Base64.getDecoder();
            byte[] b = decoder.decode(baseStrs[1]);
            for (int i = 0; i < b.length; ++i) {
                if (b[i] < 0) {
                    b[i] += 256;
                }
            }
            return new BASE64DecodedMultipartFile(b, baseStrs[0]);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    //存储图片
    public static String saveImage(String folder, String base64Image) {
        if (OssConfigConstants.isUse) {
            FileStoryInfo fileStoryInfo = null;
            if (ValidateUtil.isNotNull(folder) && !folder.endsWith("/")) {
                folder = folder + "/";
            }
            try {
                fileStoryInfo = ImageUtils.saveImage2Oss(null, getAliOssConfig(), base64ToMultipart(base64Image), folder, false);
            } catch (Exception e) {
                e.printStackTrace();
            }
            String path = fileStoryInfo == null ? null : fileStoryInfo.getUrl();
            if (ValidateUtil.isNull(path)) {
                return path;
            }
            if (ValidateUtil.isNotNull(OssConfigConstants.IMAGEBASEURL)) {
                if (ValidateUtil.isNotNull(folder)) {
                    path = path.substring(path.indexOf(folder));
                } else {
                    path = path.contains("/") ? path.substring(path.lastIndexOf("/")) : path;
                }
                path = OssConfigConstants.IMAGEBASEURL + path;
            }
            return path;
            // return fileStoryInfo.getUrl();
        } else {
            // TODO:压缩
            JYFileUtils.FilePath fp = JYFileUtils.getFile(folder, getImageName());
            if (null == fp) {
                return null;
            }
            try {
                Base64ToImageUtils.GenerateImage(base64Image, fp.file.getAbsolutePath());
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }

            // 上传到图片服务器
            upload2ImgServer(fp.fileFullPath, "", base64Image);

            return fp.dbFileFullPath;
        }
    }

    public static void upload2ImgServer(String fileFullPathName, String imageName, InputStream inputStream) {
        upload2ImgServer(fileFullPathName, imageName, inputStream, null);
    }

    public static void upload2ImgServer(String fileFullPathName, String imageName, String base64Image) {
        upload2ImgServer(fileFullPathName, imageName, null, base64Image);
    }

    private static void upload2ImgServer(String fileFullPathName, String imageName, InputStream inputStream, String base64Image) {
        if (ValidateUtil.isNull(imageName)) {
            imageName = "" + DateUtils.getCurrTime();
        }
        if (ValidateUtil.isNull(fileFullPathName)) {
            return;
        }
        if (null == inputStream && ValidateUtil.isNull(base64Image)) {
            return;
        }

        // 是否需要上传
        if (null != SYS_SETTINGS.IMAGE_SAVE_ANOTHER_SERVER && 0 == 1 - SYS_SETTINGS.IMAGE_SAVE_ANOTHER_SERVER) {
            // 需要上传
        } else {
            return;
        }
        if (ValidateUtil.isNull(SYS_CONFIG_PATH.ANOTHER_IMAGE_SERVER_URL)) {
            System.out.println("未配置图片上传接口地址，SYS_CONFIG_PATH.ANOTHER_IMAGE_SERVER_URL");
        }
        // todo 加入线程
//        try {
//            Map<String, String> textMap = new HashMap<>();
//            textMap.put("fileFullPathName", fileFullPathName);
//            HttpUploadUtil.httpClient(SYS_CONFIG_PATH.ANOTHER_IMAGE_SERVER_URL, textMap, "image", imageName, inputStream);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
        String finalImageName = imageName;
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Map<String, String> textMap = new HashMap<>();
                    textMap.put("fileFullPathName", fileFullPathName);
                    if (ValidateUtil.isNotNull(base64Image)) {
                        textMap.put("base64ImgStr", base64Image);
                    }
                    HttpUploadUtil.httpClient(SYS_CONFIG_PATH.ANOTHER_IMAGE_SERVER_URL, textMap, "image", finalImageName, inputStream);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();


    }

    /**
     * 按照 宽高 比例压缩
     *
     * @param multipartFile
     * @param width
     * @param height
     * @param out
     * @throws IOException
     */
    public static void thumbnail_w_h(MultipartFile multipartFile, int width, int height,
                                     OutputStream out) throws Exception {
        if (multipartFile == null) {
            throw new Exception("压缩文件为空");
        }
        InputStream in = multipartFile.getInputStream();
        if (in == null) {
            throw new Exception("压缩文件获取输入流出错");
        }
        BufferedImage bi = ImageIO.read(in);
        if (bi == null) {
            throw new Exception("读取的压缩文件为空");
        }
        double srcWidth = bi.getWidth(); // 源图宽度
        double srcHeight = bi.getHeight(); // 源图高度

        double scale = 1;

        if (width > 0) {
            scale = width / srcWidth;
        }
        if (height > 0) {
            scale = height / srcHeight;
        }
        if (width > 0 && height > 0) {
            scale = height / srcHeight < width / srcWidth ? height / srcHeight : width / srcWidth;
        }

        int width2 = (int) (srcWidth * scale);
        int height2 = (int) (srcHeight * scale);
        Image image = bi.getScaledInstance(width2, height2, Image.SCALE_SMOOTH);

        BufferedImage tag = new BufferedImage(width2, height2,
                BufferedImage.TYPE_INT_RGB);
        Graphics g = tag.getGraphics();
        // g.setColor(Color.RED);
        g.drawImage(image, 0, 0, null); // 绘制处理后的图
        g.dispose();
        ImageIO.write(tag, "JPEG", out);
    }
}
